package com.gxa.sso.service.impl;

import com.gxa.sso.entity.User;
import com.gxa.sso.exception.BusinessException;
import com.gxa.sso.repository.UserRepository;
import com.gxa.sso.service.UserService;
import com.gxa.sso.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    UserRepository userRepository;
    /**
     * 在spring和springboot中可直接对request实现注入/装配
     */
    @Autowired
    private HttpServletRequest request;

    //设置token前缀
    public static final String LOGIN_TOKEN="momoxixi??$";

    @Override
    public Map<String, String> login(String phone, String code) throws BusinessException {

        // 处理短信验证
        //1.获取redis服务器存储的验证码
        Object smsCode = redisTemplate.opsForValue().get(SmsServiceImpl.LOGIN_SMS + phone);

        //2.验证码失效的判断,如果为空则抛出异常
        if (StringUtils.isEmpty(smsCode)) {
            throw new BusinessException("验证码不存在或已过期");
        }

        //3.对验证码做校验, 如果不一致则抛出异常
        if (!code.equals(smsCode)) {
            throw new BusinessException("验证码验证不通过,请稍后再试");
        }

        //校验完成, 从mysql数据库中查找用户信息
        // 使用JPA完成查询: 通过手机号
        User user = userRepository.findByPhone(phone);

        // 删除验证码
        //redisTemplate.delete(SmsServiceImpl.LOGIN_SMS+phone);

        //如果用户不存在, 则匿名注册,匿名格式: "用户:"+phone , 并指定用户状态
        if (user == null) {
             user = new User();
            user.setName("用户" + phone);
            user.setStatus(1);
            user.setPhone(phone);

        }

        // userbyPhone对象非空表示用户对象存在, 判断status
        if (user.getStatus() != 1) {
            throw new BusinessException("登录失败,账号为解冻,请联系管理员,或发送邮件admin@eshop.com");
        }

        redisTemplate.delete(LOGIN_TOKEN+user.getToken());
        //生成token，存储登录信息(json),利用处理后的UUID
        String token = UUID.randomUUID().toString().replace("-","");
        user.setToken(token);
        //用户的最后一次登录时间
        user.setLastLoginTime(new Date());

        //处理登录
        // 设置ip,设置token,更新mysql
       user.setIpAddress(request.getRemoteAddr());


        // 完成持久化
        User save = userRepository.save(user);

        // 处理token
//        key 经过了加密
        String key=LOGIN_TOKEN+token;
        String value=JsonUtils.objectToJson(user);
        redisTemplate.opsForValue().set(key,value,30,TimeUnit.MINUTES);
//        redisTemplate.opsForValue().set(LOGIN_TOKEN+token,JsonUtils.objectToJson(user),30);

        // redis添加token信息和过期时间
//        redisTemplate.opsForValue().set(LOGIN+token, JsonUtils.objectToJson(user),60*60*2, TimeUnit.SECEND);
        Map<String, String> resulet = new HashMap<>();
        resulet.put("token", token);

        return resulet;
    }
    @Override
    public User queryUserByToken(String token) throws BusinessException {
        String key=LOGIN_TOKEN + token;

        Object result = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(result)) {
            throw new BusinessException("没有该用户,或者token过期,无效token,请检查或者重新登录");
        }


        //要更新失效时间
//        redisTemplate.opsForValue().set(LOGIN_TOKEN+token,60*60*2);
        return JsonUtils.jsonToObject(result.toString(),User.class);
    }
}
